package com.weishi.project.training.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weishi.common.enums.RedisConstants;
import com.weishi.common.utils.StringUtils;
import com.weishi.framework.redis.RedisCache;
import com.weishi.project.api.vo.*;
import com.weishi.project.training.domain.LeaveForm;
import com.weishi.project.training.domain.Sportsman;
import com.weishi.project.training.domain.SportsmanBodyShape;
import com.weishi.project.training.domain.SportsmanPhysicalQuality;
import com.weishi.project.training.mapper.SportsmanMapper;
import com.weishi.project.training.mapper.SportsmanPhysicalQualityMapper;
import com.weishi.project.training.service.ILeaveFormService;
import com.weishi.project.training.service.ISportsmanBodyShapeService;
import com.weishi.project.training.service.ISportsmanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * sportsmanService业务层处理
 */
@Service
public class SportsmanServiceImpl extends ServiceImpl<SportsmanMapper, Sportsman> implements ISportsmanService {

    @Autowired
    private SportsmanMapper sportsmanMapper;

    @Autowired
    private SportsmanPhysicalQualityMapper sportsmanPhysicalQualityMapper;

    @Autowired
    private ILeaveFormService leaveFormService;

    @Autowired
    private ISportsmanService sportsmanService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 身体形态 接口
     */
    @Autowired
    private ISportsmanBodyShapeService sportsmanBodyShapeService;

    //idmap
    private Map<Integer,Sportsman> sportsmanCache = new HashMap<>();

    //devIdmap
    private Map<String,Sportsman> polarIdMap = new HashMap<>();

    @Scheduled(cron = "0 0 */5 * * ?")
    private void clear(){
        sportsmanCache.clear();
        polarIdMap.clear();
    }
    private Map<Integer,Sportsman> getSportsmanCache(){
        if(sportsmanCache.isEmpty()){
            Sportsman params = new Sportsman();
            List<Sportsman> list = sportsmanMapper.selectSportsmanList(params);
            for(Sportsman sportsman : list){
                sportsmanCache.put(sportsman.getId(),sportsman);
                polarIdMap.put(sportsman.getPolarId(),sportsman);
            }
        }
        return sportsmanCache;
    }

    /**
     * 查询sportsman列表
     */
    @Override
    public List<Sportsman> selectSportsmanList(Sportsman sportsman){
        List<Sportsman> list = sportsmanMapper.selectSportsmanList(sportsman);

        try {
            for (Sportsman temp : list) {
                String status = temp.getStatus();
                if (leaveFormService.countLeaveFormById(temp.getId())) {
                    LeaveForm leaveForm = leaveFormService.queryBySportsmanId(temp.getId());
                    if(leaveForm.getCureTime()==null || leaveForm.getCureTime().after(new Date())){
                        temp.setStatus(leaveForm.getType());
                    }else{
                        temp.setStatus("0");
                    }
                }else{
                    temp.setStatus("0");
                }
                if(!temp.getStatus().equals(status)) sportsmanService.updateById(temp);
            }
        }
        catch (NullPointerException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public Sportsman qrySportsmanByCache(int sportsmanId) {
        Sportsman sportsman = redisCache.getCacheObject(RedisConstants.Sportsman_Info_Prefix + sportsmanId);
        if(sportsman==null){
            sportsman = sportsmanMapper.selectById(sportsmanId);
        }
        return sportsman;
        //return sportsmanMapper.selectById(sportsmanId);
    }

    @Override
    @Transactional
    public void saveAll(SportsmanAllVo sportsmanAllVo) {
        Sportsman sportsman = sportsmanAllVo.getSportsman();
        SportsmanPhysicalQuality sportsmanPhysicalQuality = sportsmanAllVo.getSportsmanPhysicalQuality();
        sportsman.setCtime(new Date());
        sportsmanMapper.insert(sportsman);
        sportsmanPhysicalQuality.setSportsmanId(sportsman.getId());
        sportsmanPhysicalQualityMapper.insert(sportsmanPhysicalQuality);

        // 新增身体形态
        SportsmanBodyShape sportsmanBodyShape = new SportsmanBodyShape();
        StringUtils.copyProperties(sportsman , sportsmanBodyShape);
        sportsmanBodyShape.setSportsmanId(Long.parseLong(sportsman.getId().toString()));
        sportsmanBodyShapeService.save(sportsmanBodyShape);

        clear();
    }


    @Override
    public List<Map<String, Integer>> getCountBoatFrequency(BoatFrequencyVo boatFrequencyVo) {
        return sportsmanMapper.getCountBoatFrequency(boatFrequencyVo);
    }

    @Override
    public List<Map<String, Object>> getCountPositionRatio(PositionRatioVo positionRatioVo) {
        return sportsmanMapper.getCountPositionRatio(positionRatioVo);
    }

    @Override
    public List<TrainingBoatTypeVo> getCountTrainingBoatType(Integer sportsManId) {
        return sportsmanMapper.getCountTrainingBoatType(sportsManId);
    }


    @Override
    public List<BodyFunctionAnalysisVo> getBodyFunctionAnalysisVoByweek(int sportsManId) {
        return sportsmanMapper.getBodyFunctionAnalysisVoByweek(sportsManId);
    }

    @Override
    public List<BodyFunctionAnalysisVo> getBodyFunctionAnalysisVoList(int sportsManId) {
        return sportsmanMapper.getBodyFunctionAnalysisVoList(sportsManId);
    }

    @Override
    public List<BestPartnerResultVo> getBestResultSpecialProject(SportManBestResultVo sportManBestResultVo) {
        return sportsmanMapper.getBestResultSpecialProject(sportManBestResultVo);
    }

    @Override
    public List<BestPartnerResultVo> getBestList(Integer sportsManId, Integer  kilometers, String boatType) {
        List<BestPartnerResultVo> list = sportsmanMapper.getBestList(sportsManId, kilometers, boatType);
        Map<String,BestPartnerResultVo> temp = new HashMap<>();
        for(BestPartnerResultVo bestPartnerResultVo : list){
            String key = bestPartnerResultVo.getBoatType()==null ? "lushang" : bestPartnerResultVo.getBoatType();
            BestPartnerResultVo vo = temp.get(key);
            if(vo == null || vo.getAchievement().compareTo(bestPartnerResultVo.getAchievement())>0){
                vo = bestPartnerResultVo;
                temp.put(key,vo);
            }
        }
        List<BestPartnerResultVo> ret = new ArrayList<>();
        for(String key : temp.keySet()){
            ret.add(temp.get(key));
        }
        return ret;
    }

    @Override
    public List<BestPartnerResultVo> getBestWeekList(Map<String, Object> map) {
        return sportsmanMapper.getBestWeekList(map);
    }

    @Override
    public List<BestPartnerCountVo> getBestPartnerCountVoList(int sportsManId) {
        return sportsmanMapper.getBestPartnerCountVoList(sportsManId);
    }

    @Override
    public String getNameById(int sportsManId) {
        return sportsmanMapper.getNameById(sportsManId);
    }

    @Override
    public List<InjuryCountVo> injuryCount(Map<String, Object> map) {
        Set<InjuryCountVo> set = init();
        List<InjuryCountVo> listdb = sportsmanMapper.injuryCount(map);
        for(InjuryCountVo vo : listdb){
            if(set.contains(vo)){
                set.remove(vo);
            }
            set.add(vo);
        }
        return new ArrayList<> (set);
    }

    @Override
    public List<InjuryCountVo> injuryHoursCount(Map<String, Object> map) {
        Set<InjuryCountVo> set = init();
        List<InjuryCountVo> listdb = sportsmanMapper.injuryCount(map);
        for(InjuryCountVo vo : listdb){
            if(set.contains(vo)){
                set.remove(vo);
            }
            set.add(vo);
        }
        return new ArrayList<> (set);
    }

    private Set<InjuryCountVo> init(){
        Set<InjuryCountVo> list = new HashSet<>();
        InjuryCountVo vo1 = new InjuryCountVo();
        vo1.setReason("上肢");
        vo1.setCount(0);
        vo1.setStartTime(new Date());
        list.add(vo1);
        InjuryCountVo vo2 = new InjuryCountVo();
        vo2.setReason("下肢");
        vo2.setCount(0);
        vo2.setStartTime(new Date());
        list.add(vo2);
        InjuryCountVo vo3 = new InjuryCountVo();
        vo3.setReason("躯干");
        vo3.setCount(0);
        vo3.setStartTime(new Date());
        list.add(vo3);
        InjuryCountVo vo4 = new InjuryCountVo();
        vo4.setReason("颈椎");
        vo4.setCount(0);
        vo4.setStartTime(new Date());
        list.add(vo4);
        return list;
    }

    @Override
    public List<BestPartnerResultVo> getBestResultPK(SportManBestResultVo sportManBestResultVo) {
        return sportsmanMapper.getBestResultPK(sportManBestResultVo);
    }

    @Override
    public List<OarTypeVo> getCountPulpPosition(int sportsManId) {
        return sportsmanMapper.getCountPulpPosition(sportsManId);
    }

    @Override
    public List<Map<String, Object>> selectSportsmanCountByType() {
        return sportsmanMapper.selectSportsmanCountByType();
    }

    @Override
    public List<Integer> selectSportsmanIdListBySex(int sex) {
        List<Integer> idList = new ArrayList<>();
        Sportsman sportsman = new Sportsman();
        sportsman.setSex(sex);
        List<Sportsman> list = sportsmanMapper.selectSportsmanList(sportsman);
        list.forEach( p->{
            idList.add(p.getId());
        });
        return idList;
    }

    @Override
    public Sportsman qrySportsmanByName(String sportsmanName) {
        Sportsman sportsman = new Sportsman();
        sportsman.setName(sportsmanName);
        List<Sportsman> list = sportsmanMapper.selectSportsmanList(sportsman);
        if (list!=null){
            for(Sportsman sportsman1 : list){
                if(sportsman1.getName().equals(sportsmanName)){
                    return sportsman1;
                }
            }
        }
        return null;
    }

    @Override
    public Sportsman getSportsmanByPolarId(String deviceId) {
        if(polarIdMap.isEmpty()){
            Sportsman params = new Sportsman();
            List<Sportsman> list = sportsmanMapper.selectSportsmanList(params);
            for(Sportsman sportsman : list){
                polarIdMap.put(sportsman.getPolarId(),sportsman);
            }
        }
        return polarIdMap.get(deviceId);
    }

    @Override
    public Sportsman qrySportsmanNameById(Integer id, boolean cache) {
        Sportsman sportsman = getSportsmanCache().get(id);
        if(cache && sportsman!=null){
            return sportsman;
        }else{
            return this.getById(id);
        }
    }

    @Override
    public void setHeartCount(int sportsManId, int heart) {
        redisCache.setCacheObject(RedisConstants.Heart_Rate_Sprot_Prefix + sportsManId,heart,5, TimeUnit.SECONDS);
    }

    @Override
    public int getHeartCount(int sportsManId) {
        Integer heart = redisCache.getCacheObject(RedisConstants.Heart_Rate_Sprot_Prefix + sportsManId);
        return heart==null?0:heart;
    }

    @Override
    public Sportsman getById(Integer id) {
        Sportsman sportsman = sportsmanMapper.selectById(id);

        // 查询用动员最新一条身体形态
        SportsmanBodyShape sportsmanBodyShapedb = sportsmanBodyShapeService.getNewestBySportsmanId(id);

        if(sportsmanBodyShapedb!=null){
            if(sportsmanBodyShapedb.getArmSpread() >0.0){
                sportsman.setArmSpread(sportsmanBodyShapedb.getArmSpread()); // 臂展
            }
            if(sportsmanBodyShapedb.getKneelHigh() > 0.0){
                sportsman.setKneelHigh(sportsmanBodyShapedb.getKneelHigh()); // 跪高（ 划艇 ）
            }
            if(sportsmanBodyShapedb.getSitHigh() > 0.0){
                sportsman.setSitHigh(sportsmanBodyShapedb.getSitHigh()); // 坐高
            }
            if(sportsmanBodyShapedb.getHeight() > 0.0){
                sportsman.setHeight(sportsmanBodyShapedb.getHeight()); // 身高
            }
            if(sportsmanBodyShapedb.getShoulderWidth() > 0.0){
                sportsman.setShoulderWidth(sportsmanBodyShapedb.getShoulderWidth()); // 肩宽
            }
            if(sportsmanBodyShapedb.getUpperArm() > 0.0){
                sportsman.setUpperArm(sportsmanBodyShapedb.getUpperArm()); // 上臂围
            }
            if(sportsmanBodyShapedb.getUpperArmTightening() > 0.0){
                sportsman.setUpperArmTightening(sportsmanBodyShapedb.getUpperArmTightening()); // 上臂围紧
            }
            if(sportsmanBodyShapedb.getBust() > 0.0){
                sportsman.setBust(sportsmanBodyShapedb.getBust()); // 胸围
            }
            if(sportsmanBodyShapedb.getWaistline() > 0.0){
                sportsman.setWaistline(sportsmanBodyShapedb.getWaistline()); // 腰围
            }
            if(sportsmanBodyShapedb.getHipline() > 0.0){
                sportsman.setHipline(sportsmanBodyShapedb.getHipline()); // 臀围
            }
            if(sportsmanBodyShapedb.getBodyFatPercentage() >0.0){
                sportsman.setBodyFatPercentage(sportsmanBodyShapedb.getBodyFatPercentage()); // 体脂百分比
            }
        }

        // 设置性别 为字符串类型的数字
        if(StringUtils.isNotNull(sportsman) && StringUtils.isNotNull(sportsman.getSex())){
            sportsman.setGenderChinese(SportsmanServiceImplMethod.genderString(sportsman.getSex()));
        }
        return sportsman;
    }

    @Override
    @Transactional
    public boolean save(Sportsman sportsman) {
        boolean ret = super.save(sportsman);
        clear();
        syncSportsmanBodyShape(sportsman);
        return ret;
    }

    @Override
    @Transactional
    public boolean updateById(Sportsman entity) {
        syncSportsmanBodyShape(entity);
        clear();
        return super.updateById(entity);
    }

    private void syncSportsmanBodyShape(Sportsman sportsman){
        // 新增身体形态
        SportsmanBodyShape sportsmanBodyShape = new SportsmanBodyShape();
        StringUtils.copyProperties(sportsman , sportsmanBodyShape);
        sportsmanBodyShape.setSportsmanId(sportsman.getId().longValue());
        sportsmanBodyShape.setCtime(new Date());
        sportsmanBodyShapeService.save(sportsmanBodyShape);
    }

    @Override
    public List<Sportsman> getAllSportsmanPolarId() {
        List<Sportsman> sportsmanList = new ArrayList<>();
        if(polarIdMap.isEmpty()){
            Sportsman params = new Sportsman();
            List<Sportsman> list = sportsmanMapper.selectSportsmanList(params);
            for(Sportsman sportsman : list){
                if(StringUtils.isNotEmpty(sportsman.getPolarId())){
                    polarIdMap.put(sportsman.getPolarId(),sportsman);
                }
            }
        }
        for(String key : polarIdMap.keySet()){
            sportsmanList.add(polarIdMap.get(key));
        }
        return sportsmanList;
    }
}